﻿#pragma once

namespace GLL
{
	class Exception : public std::exception
	{
		mutable String _desc;
		String _file;
		String _func;
		int _line;

	public:
		static bool IsGLLException(std::exception& e);
		Exception(const char* what, const char* file, const char* func, int line);
		Exception(const String& what, const char* file, const char* func, int line);
		virtual const char* what() const;
	};

	void ShowExceptDesc( const char* type, std::exception &e );
};

//-----------------------------------------------------------------------------
#ifndef GLL_Throw
#	define GLL_Throw(desc) { String str(desc); throw GLL::Exception(str, __FILE__, __FUNCTION__, __LINE__ );}
#endif

//-----------------------------------------------------------------------------
#ifndef GLL_OSTry
#	define GLL_OSTry __try{__noop
#endif

#ifndef GLL_OSCatch
#	define GLL_OSCatch }__except(GLL::Debug::OSException::LogCrash(GetExceptionInformation())){
#endif

#ifndef GLL_END
# define GLL_END }
#endif
//-----------------------------------------------------------------------------
#ifndef GLL_Try
#	define GLL_Try  try{__noop
#endif

#ifndef GLL_Catch_Ogre
#	ifdef GLL_OGRE
#		define GLL_Catch_Ogre	 catch(Ogre::Exception& e){GLL::ShowExceptDesc("OGRE", e);}
#	else 
#		define GLL_Catch_Ogre
#	endif
#endif

#ifndef GLL_Catch
#	define GLL_Catch  }\
	GLL_Catch_Ogre \
	catch(GLL::Exception& e){GLL::ShowExceptDesc("GLL", e);} \
	catch(std::exception& e){GLL::ShowExceptDesc("STD", e);}
#endif
